﻿//file: widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QMouseEvent>
#include <QDebug>

/**
 * @brief 构造函数。将background、clock、charge添加到stackWidget中，方便切换界面。
 *        同时安装事件过滤器。
 * @param parent - 父对象
 */
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
    , press_x(0), press_y(0), release_x(0), release_y(0)
{
    ui->setupUi(this);
    label.setParent(this);
    animation1 = new QPropertyAnimation(this);  //界面切换动画
    animation2 = new QPropertyAnimation(this);
    animationGroup.setParent(this);   //并行动画组


    //将background、clock、charge添加到stackWidget中，方便切换界面
    stackWidget.setParent(this);
    background = new Background(&stackWidget);
    clock = new Clock(&stackWidget);
    charge = new Charge(&stackWidget);
    stackWidget.addWidget(background);
    stackWidget.addWidget(clock);
    stackWidget.addWidget(charge);

//其中，filterObj参数表示要在其上实现事件过滤器函数的部件。请注意，如果我们在一个部件安装了事件过滤器，一般在其父控件上实现事件过滤器函数。
//第二个函数是 eventFilter 函数，我们在此函数中实现事件过滤器。请注意：该函数在 QObject 类中声明为一个虚函数，因此只能由 QObject 的子类继承使用
    stackWidget.installEventFilter(this);   //为 stackWidget 安装事件过滤器

    //界面布局
    layout = new QGridLayout(this);
    layout->addWidget(&stackWidget);
    layout->setContentsMargins(0, 0, 0, 0);    //设置 stackWidget 到 layout 边界的距离
    setLayout(layout);

}
/**
 * @brief Widget::~Widget -  析构函数
 */
Widget::~Widget()
{
    delete ui;

    stackWidget.removeWidget(background);
    stackWidget.removeWidget(clock);
    stackWidget.removeWidget(charge);
    animationGroup.clear();
    delete background;
    delete clock;
    delete charge;
    delete layout;

}
/**
 * @brief 绘图事件。用于实现界面滑动效果。其原理是利用 stackWidget 存放需要切换的控件。
 * 然后利用 label 保存下当前窗口的界面（截图），然后利用属性动画将切换后的控件与label组
 * 成一个动画组，模拟出滑动的效果。
 * @param obj - 产生事件的对象
 * @param event - 产生的事件
 * @return
 */
bool Widget::eventFilter(QObject *obj, QEvent *event)
{
    QMouseEvent *mouseEvent;      //鼠标事件

    if(obj != &stackWidget)
        return QWidget::eventFilter(obj, event);

    //获取鼠标按下或释放时候的坐标位置
    if(event->type() == QEvent::MouseButtonPress)
    {
        mouseEvent = static_cast<QMouseEvent *>(event);
        press_x = mouseEvent->globalX();
        press_y = mouseEvent->globalY();
    }
    else if(event->type() == QEvent::MouseButtonRelease)
    {
        mouseEvent = static_cast<QMouseEvent *>(event);
        release_x = mouseEvent->globalX();
        release_y = mouseEvent->globalY();
    }
    else
        return QWidget::eventFilter(obj, event);

    //上下移动不超过50，左右移动超过100，则视为产生滑动动作
    if( event->type() == QEvent::MouseButtonRelease )
    {
        if(release_x - press_x >= 100 && qAbs(release_y - press_y) <= 50
           && stackWidget.currentIndex() > 0)  //是否向右滑动，向右滑动则索引值 -1
        {
            label.setPixmap( stackWidget.currentWidget()->grab() );//将当前画面截图
            label.raise();       //将label置于顶层显示

            animation1->setTargetObject(&label);
            animation1->setPropertyName("geometry");
            animation1->setDuration(1000);
            animation1->setStartValue(QRect(0, 0, width(), height()));
            animation1->setEndValue(QRect(width(), 0, width(), height()));

            stackWidget.setCurrentIndex(stackWidget.currentIndex() - 1);  //先切换到右边一个界面
            animation2->setTargetObject(stackWidget.currentWidget());
            animation2->setPropertyName("geometry");
            animation2->setDuration(1000);
            animation2->setStartValue(QRect(-1 * width(), 0, width(), height()));
            animation2->setEndValue(QRect(0, 0, width(), height()));

            //将animation1和animation2合成一个动画组
            animationGroup.addAnimation(animation1);
            animationGroup.addAnimation(animation2);
            animationGroup.start();
        }
        else if(press_x - release_x >= 100 && qAbs(release_y - press_y) <= 50
           && stackWidget.currentIndex() < stackWidget.count() - 1)//是否向左滑动，向左滑动则索引值 +1
        {
            label.setPixmap( stackWidget.currentWidget()->grab() );//将当前画面截图
            label.raise();       //将label置于顶层显示

            animation1->setTargetObject(&label);
            animation1->setPropertyName("geometry");
            animation1->setDuration(1000);
            animation1->setStartValue(QRect(0, 0, width(), height()));
            animation1->setEndValue(QRect(-1 * width(), 0, width(), height()));

            stackWidget.setCurrentIndex(stackWidget.currentIndex() + 1);  //先切换到左边一个界面
            animation2->setTargetObject(stackWidget.currentWidget());
            animation2->setPropertyName("geometry");
            animation2->setDuration(1000);
            animation2->setStartValue(QRect(width(), 0, width(), height()));
            animation2->setEndValue(QRect(0, 0, width(), height()));

            //将animation1和animation2合成一个动画组
            animationGroup.addAnimation(animation1);
            animationGroup.addAnimation(animation2);
            animationGroup.start();

        }
    }

    return QWidget::eventFilter(obj, event);
}
